using Tutorial1_Spawner;
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;

namespace Tutorial2_SinMove
{
    [BurstCompile]
    [UpdateInGroup(typeof(Tutorial02SystemGroup))]
    public partial struct SinMoveSystem : ISystem
    {
        public void OnCreate(ref SystemState state)
        {
            Debug.Log("SinMoveSystem  OnCreate");
        }

        public void OnDestroy(ref SystemState state)
        {
            
        }
        
        public void OnUpdate(ref SystemState state)
        {
            // 方法一
            // 在System中查询得到，然后直接修改值
            // 效果差不多的：foreach(var entity in SystemAPI.Query<RefRW<LocalTransform>, RefRO<BlueObjTag>>() )
            // EntityQueryBuilder builder = new EntityQueryBuilder(Allocator.TempJob).WithAll<LocalTransform, CubeTag>();
            // var query = state.GetEntityQuery(builder);
            // var entityArray = query.ToEntityArray(Allocator.TempJob);
            // foreach (Entity entity in entityArray)
            // {
            //     var trans = state.World.EntityManager.GetComponentData<LocalTransform>(entity);
            //     var pos = trans.Position;
            //     var distance = Vector3.Distance(pos, Vector3.zero);
            //     var finalPos = Vector3.up * math.sin((float) SystemAPI.Time.ElapsedTime * 3 + distance * 0.2f);
            //     trans.Position += new float3(finalPos.x, finalPos.y, finalPos.z);
            //     state.EntityManager.SetComponentData(entity, trans);
            // }
            
            
            // 方法二 用JOB查询得到
            SinMoveJob sinMoveJob = new SinMoveJob()
            {
                ElapsedTime = (float)SystemAPI.Time.ElapsedTime
            };
            sinMoveJob.Schedule();
        }
    }

    public partial struct SinMoveJob : IJobEntity
    {
        public float ElapsedTime;

        /// <summary>
        /// 查询满足参数的Entity, 此处是Entity满足CubeTag这个ComponentData且满足LocalTransform
        /// in 表示参数是只读的，无法被修改，并且传递的参数值仅在方法内部使用
        /// </summary>
        private void Execute(ref LocalTransform localTransform, in CubeTag cubeTag)
        {
            var distance = Vector3.Distance(localTransform.Position, Vector3.zero);
            var signY = Vector3.up * math.sin(ElapsedTime * 3 + distance * 0.2f);
            localTransform.Position += new float3(0, signY.y, 0);
        }
    }
}